package net.ftzcode.component

import com.google.gson.*
import com.google.gson.stream.MalformedJsonException
import org.slf4j.LoggerFactory
import org.springframework.core.MethodParameter
import org.springframework.web.bind.support.WebDataBinderFactory
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.method.support.ModelAndViewContainer
import javax.servlet.http.HttpServletRequest
import java.math.BigInteger


/**
 * Created by YanCheng on 2016/11/3.
 */


open class JsonMethodArgumentResolver : HandlerMethodArgumentResolver {


    private val gson = GsonBuilder().setPrettyPrinting().create()
    private val jsonParser=JsonParser()
    private var content = ""

    private var logger = LoggerFactory.getLogger(javaClass)

    override fun supportsParameter(methodParameter: MethodParameter): Boolean {
        return true
    }

    @Throws(Exception::class)
    override fun resolveArgument(methodParameter: MethodParameter, modelAndViewContainer: ModelAndViewContainer, nativeWebRequest: NativeWebRequest, webDataBinderFactory: WebDataBinderFactory): Any? {
        val request = nativeWebRequest.getNativeRequest(HttpServletRequest::class.java)
        if (!request.contentType.contains("application/json")) {
            return null
        }
        content = request.reader.readText()
        logger.info("获取前端的json的数据字符串内容是：" + content)
        try {
            val jsonObject = jsonParser.parse(content).asJsonObject
            if (jsonObject.get(methodParameter.parameterName) == null) {
                return null
            }
            if (jsonObject.get(methodParameter.parameterName).isJsonObject) {
                val nodeJsonObject = jsonObject.getAsJsonObject(methodParameter.parameterName)
                if (nodeJsonObject != null) {
                    return gson.fromJson(nodeJsonObject.toString(), methodParameter.parameterType)
                }
            } else if (jsonObject.get(methodParameter.parameterName).isJsonPrimitive) {
                when {
                    methodParameter.parameterType.isAssignableFrom(Int::class.java) -> return jsonObject.get(methodParameter.parameterName).asInt
                    methodParameter.parameterType.isAssignableFrom(Double::class.java) -> return jsonObject.get(methodParameter.parameterName).asDouble
                    methodParameter.parameterType.isAssignableFrom(String::class.java) -> return jsonObject.get(methodParameter.parameterName).asString
                    methodParameter.parameterType.isAssignableFrom(BigInteger::class.java) -> return jsonObject.get(methodParameter.parameterName).asBigInteger
                    else -> {
                    }
                }
            } else if (jsonObject.get(methodParameter.parameterName).isJsonArray) {
                val nodeJsonObject = jsonObject.getAsJsonArray(methodParameter.parameterName)
                return gson.fromJson(nodeJsonObject.toString(), methodParameter.parameterType)
            }

        } catch (e: Exception) {
            e.printStackTrace()
            throw MalformedJsonException("解析json数据发生错误,可能是json格式错误或者参数无法匹配")
        }


        return null
    }


}
